'use strict';

const Controller = require('egg').Controller;

class NspController extends Controller {
  // 验证token
  async checkToken(token) {
    // 解构
    const {
      ctx,
      app,
      service,
      helper
    } = this;
    const nsp = app.io.of('/');
    const socket = ctx.socket;
    const id = socket.id;
    // 1.验证token
    if (!token) {
      socket.emit(id, ctx.helper.parseMsg('error', '你没有权限访问该接口！'))
      return false
    }
    // 2.根据token解密，获取用户信息
    let user = {}
    try {
      user = ctx.checkToken(token)

    } catch (error) {
      let fail = error.name === 'TokenExpiredError' ? 'token 已过期! 请重新获取令牌' : 'Token 令牌不合法!';
      socket.emit(id, ctx.helper.parseMsg('error', fail))
      return false
    }

    // 3.判断当前用户是否登录
    let t = await service.cache.get('user_' + user.id)
    if (!t || t !== token) {
      socket.emit(id, ctx.helper.parseMsg('error', 'Token令牌不合法'))
      return false
    }
    // 4.获取当前用户，验证当前用户是否被禁用
    user = await app.model.User.findByPk(user.id)
    if (!user) {
      socket.emit(id, ctx.helper.parseMsg('error', '用户不存在或已被禁用'))
      return false
    }
    return user
  }
  // 加入直播间
  async joinLive() {
    let {
      ctx,
      app,
      service
    } = this
    const nsp = app.io.of('/');
    // 前端传过来的参数
    let message = ctx.args[0]
    // 获取当前直播id 以及用户token
    let {
      live_id,
      token
    } = message
    // 获取当前用户
    let user = await this.checkToken(token)
    // 当前的socket链接
    const socket = ctx.socket
    const id = socket.id
    // 验证当前直播间是否存在或是处于直播中
    let msg = await service.live.checkStatus(live_id)
    if (msg) {
      socket.emit(id, ctx.helper.parseMsg('error', msg))
      return
    }
    // 用户加入房间
    const room = 'live_' + live_id
    socket.join(room)
    const rooms = [room]
    // 加入redis存储中 获取redis 判断列表当前用户是否存在--如果存在，排在最前，如果不存在，加入其中
    let list = await service.cache.get('userList_' + room)
    list = list ? list : []
    list = list.filter(item => item.user_id !== user.id)
    list.unshift({
      id: user.id,
      name: user.username,
      avatar: user.avatar
    })
    service.cache.set('userList_' + room, list)
    // 更新在线用户列表
    nsp.adapter.clients(rooms, (err, clients) => {
      console.log('#online_join', clients);
      nsp.to(room).emit('online', {
        clients,
        action: 'join',
        user: {
          id: user.id,
          name: user.username,
          avatar: user.avatar
        },
        data: list
      })
    })
    // 加入播放历史记录中--
    let liveUser = await app.model.LiveUser.findOne({
      where: {
        user_id: user.id,
        live_id
      }
    })
    // 直播间是否存在
    if (!liveUser) {
      app.model.LiveUser.create({
        user_id: user.id,
        live_id
      })
      let live = await service.live.exist(live_id)
      if (live) {
        live.increment({
          look_count: 1
        })
      }

    }
    // 总观看人数+1

  }


  // 离开直播间
  async leaveLive() {
    let {
      ctx,
      app,
      service
    } = this
    const nsp = app.io.of('/');
    // 前端传过来的参数
    let message = ctx.args[0]
    // 获取当前直播id 以及用户token
    let {
      live_id,
      token
    } = message
    // 获取当前用户
    let user = this.checkToken(token)
    // 当前的socket链接
    const socket = ctx.socket
    const id = socket.id
    // 验证当前直播间是否存在或是处于直播中
    let msg = await service.live.checkStatus(live_id)
    if (msg) {
      socket.emit(id, ctx.helper.parseMsg('error', msg, {
        notoast: true
      }))
      return
    }
    // 用户加入房间
    const room = 'live_' + live_id
    socket.leave(room)
    const rooms = [room]
    // 更新在线用户列表
    nsp.adapter.clients(rooms, (err, clients) => {
      console.log('#online_level', clients);
      nsp.to(room).emit('online', {
        clients,
        action: 'level',
        user: {
          id: user.id,
          name: user.username,
          avatar: user.avatar
        }
      })
    })
    // 加入redis存储中 获取redis 判断列表当前用户是否存在--如果存在，排在最前，如果不存在，加入其中
    let list = await service.cache.get('userList_' + room)
    list = list
    if (list) {
      list = list.filter(item => item.user_id !== user.id)
      service.cache.set('userList_' + room, list)
    }
  }

  // 发送礼物
  async gift() {
    // 结构
    const {
      ctx,
      app,
      service,
      helper
    } = this
    // 获取必要阐述
    const nsp = app.io.of('/')
    const socket = ctx.socket
    const id = socket.id
    const message = ctx.args[0] || {}
    const {
      live_id,
      token,
      gift_id
    } = message
    // 验证用户-用户不存在
    let user = await this.checkToken(token)
    if (!user) {
      return
    }
    try {
      // 验证直播间状态-直播间状态为非直播中
      let msg=await service.live.checkStatus(live_id)
      if(msg){
        socket.emit(id,ctx.helper.parseMsg('error',msg))
        return
      }
      // 验证礼物是否存在-礼物不存在
      let gift=await service.gift.exist(gift_id)
      if(!gift){
        socket.emit(id,ctx.helper.parseMsg('error','礼物不存在'))
        return
      }
      // 判断用户的金币是否满足购买该礼物-金币不足
      if(user.coin<gift.coin){
        socket.emit(id,ctx.helper.parseMsg('error','金币不足，请充值'))
        return
      }
      // 扣除金币
      user.coin-=gift.coin
      await user.save()
      // 拿到直播间-增加金币数量
      let live=await service.live.exist(live_id)
      live.coin+=gift.coin
      await live.save()
      // 写入礼物记录
      await app.model.LiveGift.create({
        user_id:user.id,
        gift_id,
        live_id
      })
      // 推送消息到前端
      let room='live_'+live_id
      nsp.to(room).emit('gift',{
        avatar: user.avatar,
        username: user.nickname || user.username,
        gift_image: gift.image,
        gift_name: gift.name,
        gift_coin:gift.coin,
        num: 1
      });
    } catch (error) {
      app.logger.error(error);
    }
  }

  // 发送评论
  async comment() {
    // 结构
    const {
      ctx,
      app,
      service,
      helper
    } = this
    // 获取必须的参数 
    const nsp = app.io.of('/')
    const socket = ctx.socket
    const message = ctx.args[0] || {}
    const id = socket.id
    const {
      live_id,
      data,
      token
    } = message
    // 验证用户
    let user = await this.checkToken(token)
    if (!user) {
      return
    }

    try {
      // 验证直播状态
      let msg = await service.live.checkStatus(live_id)
      if (msg) {
        socket.emit(id, ctx.helper.parseMsg('error', msg))
        return
      }
      // 判断内容不能为空
      if (!data) {
        socket.emit(id, ctx.helper.parseMsg('error', '弹幕不能为空'))
        return
      }
      // 推送弹幕到房间
      let room = 'live_' + live_id
      nsp.to(room).emit('comment', {
        user: {
          id: user.id,
          name: user.nickname || user.username,
          avatar: user.avatar,
        },
        content: data,
        id: ctx.randomString(20)
      })
    } catch (error) {
      app.logger.error(error);
    }
  }

}

module.exports = NspController;